<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta http-equiv="Content-Security-Policy" content="default-src 'self' 'unsafe-inline' 'unsafe-eval' data: blob:; connect-src * data: blob:">
    <meta name="robots" content="noindex">
    <title>Scaffolding Demo</title>
    <style>
      body {
        background-color: black;
        color: white;
        font-family: sans-serif;
        overflow: hidden;
      }
      [hidden] {
        display: none !important;
      }
      h1 {
        font-weight: normal;
      }
      a {
        color: inherit;
        text-decoration: underline;
        cursor: pointer;
      }

      #app, #loading, #error, #launch {
        position: absolute;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
      }
      .screen {
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        text-align: center;
        cursor: default;
        user-select: none;
        -webkit-user-select: none;
        background-color: black;
      }
      #launch {
        background-color: rgba(0, 0, 0, 0.7);
        cursor: pointer;
      }
      .green-flag {
        width: 80px;
        height: 80px;
        padding: 16px;
        border-radius: 100%;
        background: rgba(255, 255, 255, 0.75);
        border: 3px solid hsla(0, 100%, 100%, 1);
        display: flex;
        justify-content: center;
        align-items: center;
        box-sizing: border-box;
      }
      .progress-bar-outer {
        border: 1px solid currentColor;
        height: 10px;
        width: 200px;
        max-width: 200px;
      }
      .progress-bar-inner {
        height: 100%;
        width: 0;
        background-color: currentColor;
      }
      .control-button {
        width: 2rem;
        height: 2rem;
        padding: 0.375rem;
        border-radius: 0.25rem;
        margin-top: 0.5rem;
        margin-bottom: 0.5rem;
        user-select: none;
        -webkit-user-select: none;
        cursor: pointer;
        border: 0;
        border-radius: 4px;
      }
      .control-button:hover {
        background: hsla(0, 100%, 65%, 0.15);
      }
      .control-button.active {
        background: hsla(0, 100%, 65%, 0.35);
      }
      .fullscreen-button {
        background: white !important;
      }
      #error-information {
        font-family: monospace;
      }
    </style>
  </head>
  <body>
    <noscript>Enable JavaScript</noscript>

    <div id="app"></div>

    <div id="launch" class="screen" hidden title="Click to start">
      <div class="green-flag">
        <svg viewBox="0 0 16.63 17.5" width="42" height="44">
          <defs><style>.cls-1,.cls-2{fill:#4cbf56;stroke:#45993d;stroke-linecap:round;stroke-linejoin:round;}.cls-2{stroke-width:1.5px;}</style></defs>
          <path class="cls-1" d="M.75,2A6.44,6.44,0,0,1,8.44,2h0a6.44,6.44,0,0,0,7.69,0V12.4a6.44,6.44,0,0,1-7.69,0h0a6.44,6.44,0,0,0-7.69,0"/>
          <line class="cls-2" x1="0.75" y1="16.75" x2="0.75" y2="0.75"/>
        </svg>
      </div>
    </div>

    <div id="loading" class="screen">
      <div class="progress-bar-outer"><div class="progress-bar-inner" id="loading-inner"></div></div>
    </div>

    <div id="error" class="screen" hidden>
      <h1>Error</h1>
      <p id="error-information"></p>
    </div>

    <!-- If using Scaffolding as a library, update this path to where your scaffolding-[full|min].js is located. -->
    <!-- This could also be a jsdelivr URL. -->
    <script src="scaffolding/scaffolding-full.js"></script>

    <script>
      const PROJECT_ID = location.hash.substr(1) || '1';

      const appElement = document.getElementById('app');
      const launchScreen = document.getElementById('launch');
      const loadingScreen = document.getElementById('loading');
      const loadingInner = document.getElementById('loading-inner');
      const errorScreen = document.getElementById('error');
      const errorInformation = document.getElementById('error-information');

      const scaffolding = new Scaffolding.Scaffolding();
      scaffolding.setup();
      scaffolding.appendTo(appElement);

      const {storage, vm} = scaffolding;
      storage.addWebStore(
        [storage.AssetType.ImageVector, storage.AssetType.ImageBitmap, storage.AssetType.Sound],
        (asset) => `https://assets.scratch.mit.edu/internalapi/asset/${asset.assetId}.${asset.dataFormat}/get/`
      );
      const setProgress = (progress) => {
        loadingInner.style.width = `${progress * 100}%`;
      }
      storage.onprogress = (total, loaded) => {
        setProgress(0.2 + (loaded / total) * 0.8)
      };
      setProgress(0.1);

      const greenFlagButton = document.createElement('img');
      greenFlagButton.src = 'data:image/svg+xml,' + encodeURIComponent('<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16.63 17.5"><path d="M.75 2a6.44 6.44 0 017.69 0h0a6.44 6.44 0 007.69 0v10.4a6.44 6.44 0 01-7.69 0h0a6.44 6.44 0 00-7.69 0" fill="#4cbf56" stroke="#45993d" stroke-linecap="round" stroke-linejoin="round"/><path stroke-width="1.5" fill="#4cbf56" stroke="#45993d" stroke-linecap="round" stroke-linejoin="round" d="M.75 16.75v-16"/></svg>');
      greenFlagButton.className = 'control-button';
      greenFlagButton.addEventListener('click', () => {
        scaffolding.greenFlag();
      });
      scaffolding.addEventListener('PROJECT_RUN_START', () => {
        greenFlagButton.classList.add('active');
      });
      scaffolding.addEventListener('PROJECT_RUN_STOP', () => {
        greenFlagButton.classList.remove('active');
      });
      scaffolding.addControlButton({
        element: greenFlagButton,
        where: 'top-left'
      });

      const stopAllButton = document.createElement('img');
      stopAllButton.src = 'data:image/svg+xml,' + encodeURIComponent('<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 14 14"><path fill="#ec5959" stroke="#b84848" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" d="M4.3.5h5.4l3.8 3.8v5.4l-3.8 3.8H4.3L.5 9.7V4.3z"/></svg>');
      stopAllButton.className = 'control-button';
      stopAllButton.addEventListener('click', () => {
        scaffolding.stopAll();
      });
      scaffolding.addControlButton({
        element: stopAllButton,
        where: 'top-left'
      });

      if (document.fullscreenEnabled || document.webkitFullscreenEnabled) {
        let isFullScreen = !!(document.fullscreenElement || document.webkitFullscreenElement);
        const fullscreenButton = document.createElement('img');
        fullscreenButton.className = 'control-button fullscreen-button';
        fullscreenButton.addEventListener('click', () => {
          if (isFullScreen) {
            if (document.exitFullscreen) {
              document.exitFullscreen();
            } else if (document.webkitExitFullscreen) {
              document.webkitExitFullscreen();
            }
          } else {
            if (document.body.requestFullscreen) {
              document.body.requestFullscreen()
            } else if (document.body.webkitRequestFullscreen) {
              document.body.webkitRequestFullscreen();
            }
          }
        });
        const updateFullScreen = () => {
          isFullScreen = !!(document.fullscreenElement || document.webkitFullscreenElement);
          if (isFullScreen) {
            fullscreenButton.src = 'data:image/svg+xml,' + encodeURIComponent('<svg width="20" height="20" xmlns="http://www.w3.org/2000/svg"><g fill="#575E75" fill-rule="evenodd"><path d="M12.662 3.65l.89.891 3.133-2.374a.815.815 0 011.15.165.819.819 0 010 .986L15.467 6.46l.867.871c.25.25.072.664-.269.664L12.388 8A.397.397 0 0112 7.611V3.92c0-.341.418-.514.662-.27M7.338 16.35l-.89-.89-3.133 2.374a.817.817 0 01-1.15-.166.819.819 0 010-.985l2.37-3.143-.87-.871a.387.387 0 01.27-.664L7.612 12a.397.397 0 01.388.389v3.692a.387.387 0 01-.662.27M7.338 3.65l-.89.891-3.133-2.374a.815.815 0 00-1.15.165.819.819 0 000 .986l2.37 3.142-.87.871a.387.387 0 00.27.664L7.612 8A.397.397 0 008 7.611V3.92a.387.387 0 00-.662-.27M12.662 16.35l.89-.89 3.133 2.374a.817.817 0 001.15-.166.819.819 0 000-.985l-2.368-3.143.867-.871a.387.387 0 00-.269-.664L12.388 12a.397.397 0 00-.388.389v3.692c0 .342.418.514.662.27"/></g></svg>');
          } else {
            fullscreenButton.src = 'data:image/svg+xml,' + encodeURIComponent('<svg width="20" height="20" xmlns="http://www.w3.org/2000/svg"><g fill="#575E75" fill-rule="evenodd"><path d="M16.338 7.35l-.89-.891-3.133 2.374a.815.815 0 01-1.15-.165.819.819 0 010-.986l2.368-3.142-.867-.871a.387.387 0 01.269-.664L16.612 3a.397.397 0 01.388.389V7.08a.387.387 0 01-.662.27M3.662 12.65l.89.89 3.133-2.374a.817.817 0 011.15.166.819.819 0 010 .985l-2.37 3.143.87.871c.248.25.071.664-.27.664L3.388 17A.397.397 0 013 16.611V12.92c0-.342.418-.514.662-.27M3.662 7.35l.89-.891 3.133 2.374a.815.815 0 001.15-.165.819.819 0 000-.986L6.465 4.54l.87-.871a.387.387 0 00-.27-.664L3.388 3A.397.397 0 003 3.389V7.08c0 .341.418.514.662.27M16.338 12.65l-.89.89-3.133-2.374a.817.817 0 00-1.15.166.819.819 0 000 .985l2.368 3.143-.867.871a.387.387 0 00.269.664l3.677.005a.397.397 0 00.388-.389V12.92a.387.387 0 00-.662-.27"/></g></svg>');
          }
        };
        updateFullScreen();
        document.addEventListener('fullscreenchange', updateFullScreen);
        document.addEventListener('webkitfullscreenchange', updateFullScreen);
        scaffolding.addControlButton({
          element: fullscreenButton,
          where: 'top-right'
        });
      }

      scaffolding.addCloudProvider(new Scaffolding.Cloud.WebSocketProvider('wss://clouddata.turbowarp.org', PROJECT_ID));

      const getProjectData = async () => {
        const metadataResponse = await fetch(`https://trampoline.turbowarp.org/api/projects/${PROJECT_ID}`);
        if (!metadataResponse.ok) {
          throw new Error('Failed to load project metadata. It is probably unshared.');
        }
        const projectMetadata = await metadataResponse.json();
        const token = projectMetadata.project_token;
        const dataResponse = await fetch(`https://projects.scratch.mit.edu/${PROJECT_ID}?token=${token}`);
        if (!dataResponse.ok) {
          throw new Error('Failed to load project data.');
        }
        return dataResponse.arrayBuffer();
      };

      const run = async () => {
        const projectData = await getProjectData();
        setProgress(0.1);
        await scaffolding.loadProject(projectData);
        scaffolding.setUsername('123');
        setProgress(1);
        loadingScreen.hidden = true;
        launchScreen.hidden = false;
        launchScreen.addEventListener('click', () => {
          launchScreen.hidden = true;
          scaffolding.start();
        });
        launchScreen.focus();
      };

      const handleError = (error) => {
        console.error(error);
        errorScreen.hidden = false;
        errorInformation.textContent = `${error}`;
      };

      run().catch(handleError);
    </script>
  </body>
</html>
